我們在昨天教給大家設定Security,這樣設置下,無論哪個API都需要有帳號密碼,而這個帳號密碼由於我們沒有設置,所以是由系統指定一個user,並且給一個密碼讓我們使用。
接下來我們要學更進階一點的功能,就是設定不同的權限,以及給系統一組指定的帳號密碼。
那就讓我們開始吧!
首先,讓我們來在config檔中設定我們的帳號密碼以及權限。Spring Secuirty其實已經有一個class,我們只要呼叫這個class就可以,這個就是UserDatailsService
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager();
}
我們可以在這個頁面中宣告我們要的帳號密碼,以及他所有的權限,就可以在網址中設定我要甚麼樣子的權限才能夠取得資料,我們先設定Eric跟admin的資料,設定完成後就會如以下的程式碼。
package net.Eric.accounting.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import lombok.AllArgsConstructor;
@Configuration
@AllArgsConstructor
public class SpringSecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf((csrf) -> csrf.disable())
.authorizeHttpRequests((authorize)->{
authorize.anyRequest().authenticated();
}).httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails Eric = User.builder()
.username("Eric")
.password(passwordEncoder().encode("123321"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(Eric,admin);
}
}
接下來,我們要設定那些權限可以使用那些網址,這可以用這個方法
authorize.requestMatchers(HttpMethod.POST,"/api/**").hasRole("ADMIN");
其實很簡單,我們可以指定是哪個HttpMethod,以及是哪個網址,hasRole就如同字面上意義,就是哪個權限可以訪問。
我們先設定Post資料只有admin才有,然後Get的資料是USER跟ADMIN都可以,完成後就會如同以下的程式碼
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf((csrf) -> csrf.disable())
.authorizeHttpRequests((authorize)->{
authorize.requestMatchers(HttpMethod.POST,"/api/**").hasRole("ADMIN");
authorize.requestMatchers(HttpMethod.GET,"/api/**").hasAnyRole("ADMIN","USER");
authorize.anyRequest().authenticated();
}).httpBasic(Customizer.withDefaults());
return http.build();
}
接下來我們就要開始測試
首先先測試Post的權限,我們使用剛剛設定的User帳號去新增accounts資料,因為我們權限的設定,USER並沒有權限去新增資料,就會回傳403 forbidden的結果,就如同以下Postman結果
再來,我們使用admin的帳號新增資料,就會出現成功的畫面,並且新增資料進資料庫
再來我們測試Get方法,這個方法是USER跟ADMIN都可以的,所以我們先用USER來測試
再來用admin來測試
到了這裡,大家就成功設置新的帳號密碼,以及不同的腳色權限可以連線到不同的網址的方式,增加了對於網站的安全性保護了!